/* $Id: HtmlToolkit.java 113 2011-02-01 19:37:39Z altdotua@gmail.com $ */

package alt.djudge.frontend.server.gui;

import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.lang.StringEscapeUtils;

import alt.djudge.frontend.server.datatypes.SubmissionEntry;
import alt.djudge.frontend.server.datatypes.scores.ProblemUserScoreEntry;
import alt.djudge.frontend.server.utils.Linker;


public class HtmlToolkit
{
	private StringBuilder sb = new StringBuilder();

	/* Background colors for different judgments */
	public final static String colorAC = "#aaffaa";

	public final static String colorCE = "#cccccc";
	
	public final static String colorPending = "#ffff00";
	
	public final static String colorWA = "#ffaaaa";
	
	public final static String colorMLE = colorWA;
	
	public final static String colorTLE = colorWA;
	
	public final static String colorRE = colorWA;

	public static String formatDate(Date date)
	{
		return date.toString();
	}
	
	public static String formatSourceSize(Integer size)
	{
		size = (size + 99) / 100;
		return "" + (size / 10) + "." + (size % 10) + " КБ";
	}
	
	public static String formatJudgement(String j)
	{
		if ("CE".equalsIgnoreCase(j))
			return "Помилка компіляції";
		if ("RE".equalsIgnoreCase(j))
			return "Помилка часу виконання";
		if ("TLE".equalsIgnoreCase(j))
			return "Ліміт часу";
		if ("MLE".equalsIgnoreCase(j))
			return "Ліміт памяті";
		if ("AC".equalsIgnoreCase(j))
			return "Зараховано";
		if ("WA".equalsIgnoreCase(j))
			return "Неправильна відповідь";
		if ("N/A".equalsIgnoreCase(j))
			return "-";
		return j;
	}
	
	public static Date getUserTime(Date gmtTime, TimeZone zone)
	{
		return gmtTime;
	}
	
	public static String formatMonitorCell(SubmissionEntry s)
	{
		if (s == null)
			return "<td>-</td>";
		if ("AC".equals(s.getJudgement()))
			return "<td bgcolor='#aaffaa'><a href='" + Linker.link("submission.jsp?submission_id=" + s.getId()) + "'><b>" + s.getScore() + "</b></a></td>";
		return "<td><a href='" + Linker.link("submission.jsp?submission_id=" + s.getId()) + "'>" + s.getScore() + "</a></td>";
	}
	
	public static String formatContestTime(Long minutes)
	{
		if (minutes == null)
			return "??:??";
		Long days = minutes / 60 / 24;
		Long hours = (minutes / 60) % 24;
		minutes %= 60;
		if (days == 1)
			return "" + days + " day " + hours + ":" + (minutes  >= 10 ? minutes : "0" + minutes);
		if (days > 1)
			return "" + days + " day(s) " + hours + ":" + (minutes  >= 10 ? minutes : "0" + minutes);
		return hours + ":" + (minutes  >= 10 ? minutes : "0" + minutes);
	}
	
	public static String formatContestTimeSeconds(Long second)
	{
		return formatContestTime(second / 60) + ":" + ((second % 60 > 10) ? second % 60 : "0" + (second % 60));
	}
	
	public static String formatScore(Integer score)
	{
		return score >= 0 ? "" + score : "-";
	}
	
	public static String formatMonitorCell(ProblemUserScoreEntry s)
	{
		if (s.getAcceptedCount() == 0 && s.getRejectedCount() == 0 && s.getPendingCount() == 0)
			return "<td>-</td>";
		if (s.getAccepted())
			return "<td bgcolor='#aaffaa'><a href='" + Linker.link("submission.jsp?submission_id=" + s.getMaxScoreId()) + "'><b>" + s.getMaxScore() + "</b></a></td>";
		else if (s.getPendingCount() > 0)
			return "<td bgcolor='#ffffaa'>-</td>";
		return "<td><a href='" + Linker.link("submission.jsp?submission_id=" + s.getMaxScoreId()) + "'>" + s.getMaxScore() + "</a></td>";
	}
	
	
	public static String formatMonitorCellACM(ProblemUserScoreEntry s)
	{
		if (s.getAcceptedCount() == 0 && s.getRejectedCount() == 0 && s.getPendingCount() == 0)
			return "<td>-</td>";
		if (s.getAccepted())
			return "<td bgcolor='#aaffaa'><a href='" + Linker.link("submission.jsp?submission_id=" + s.getMaxScoreId()) + "'><b>" + (s.getRejectedCount() == 0 ? "+" : "+" + s.getRejectedCount()) + "</b></a></td>";
		return "<td bgcolor='" + (s.getPendingCount() > 0 ? "#ffffaa" : "#ffaaaa") + "'><a href='" + Linker.link("submission.jsp?submission_id=" + s.getMaxScoreId()) + "'><b>" + "-" + s.getRejectedCount() + "</b></a></td>";
	}
	
	public static String formatState(Integer state)
	{
		return state == -1 ? "На перевірці" : state == 0 ? "В черзі" : "ОК";
	}

	public static String formatMemory(Integer memorySize)
	{
		return formatMemory(memorySize.longValue());
	}
	
	public static String formatMemory(Long memorySize)
	{
		return memorySize >= 0 ? (memorySize / 1024) + " КБ" : "-";
	}
	
	public static String formatRuntime(Integer time)
	{
		return time >= 0 ? "" + time + " мс" : "-";
	}
	
	protected void startTable()
	{
		append("<table border=\"1\" class=\"b1\">");
	}

	protected void startTable(String clazz)
	{
		startTable(clazz, null);
	}
	
	protected void startTable(String clazz, String width)
	{
		startTable(clazz, width, null);
	}

	protected void startTable(String clazz, String width, String style)
	{
		startTable(clazz, width, style, null);
	}

	protected void appendAttribute(String attributeName, String attributeValue)
	{
		if (attributeValue != null && attributeValue.length() > 0)
			append(" " + attributeName + "='" + attributeValue + "'");
	}
	
	protected void startTable(String clazz, String width, String style, String border)
	{
		append("<table");
		appendAttribute("width", width);
		appendAttribute("border", border);
		appendAttribute("class", clazz);
		appendAttribute("style", style);
		append(">");
	}

	protected void endTable()
	{
		append("</table>\n");
	}

	protected void startTableRow()
	{
		startTableRow(null, null);
	}

	protected void startTableRow(String clazz)
	{
		startTableRow(clazz, null);
	}

	protected void startTableRow(String clazz, String style)
	{
		append("<tr");
		appendAttribute("align", "center");
		appendAttribute("class", clazz);
		appendAttribute("style", style);
		append(">");
	}

	protected void endTableRow()
	{
		append("</tr>\n");
	}

	protected String escapeHtml(String text)
	{
		return StringEscapeUtils.escapeHtml(text);
	}

	protected void addTableHeader(Object title)
	{
		addTableHeader(title.toString(), null);
	}
	
	protected void addTableHeader(String title)
	{
		addTableHeader(title, null);
	}
	
	protected void addTableHeader(String title, String clazz)
	{
		addTableHeader(title, clazz, null);
	}
	
	protected void startTableHeader(String clazz, String style)
	{
		append("<th align='center'");
		if (clazz != null && clazz.length() > 0)
			 append("class='" + clazz + "'");
		if (style != null && style.length() > 0)
			 append("style='" + style + "'");
		append(">");
	}
	
	protected void endTableHeader()
	{
		append("</th>\n");	
	}
	
	protected void startTableData(String clazz, String style)
	{
		append("<td align='center'");
		if (clazz != null && clazz.length() > 0)
			 append("class='" + clazz + "'");
		if (style != null && style.length() > 0)
			 append("style='" + style + "'");
		append(">");
	}
	
	protected void endTableData()
	{
		append("</td>");	
	}
	
	protected void addTableHeader(String title, String clazz, String style)
	{
		startTableHeader(clazz, style);
		append(title);
		endTableHeader();
	}

	protected void addTableData(Object o)
	{
		addTableData(o.toString());
	}

	private void addTableData(String name)
	{
		append("<td>" + name + "</td>");
	}

	protected void addTableData(Object o, String link)
	{
		addTableData(linkify(o.toString(), link));
	}
	
	protected void addTableData(String title, String clazz, String style)
	{
		startTableData(clazz, style);
		append(title);
		endTableData();
	}

	protected String linkify(String text, String href)
	{
		return "<a href=\"" + href + "\">" + text + "</a>";
	}
	
	protected String getResult()
	{
		return sb.toString();
	}
	
	protected final void append(String str)
	{
		sb.append(str);
	}
	
	protected final void append(Object obj)
	{
		sb.append(obj);
	}
}
